import * as http from 'http';
import * as httpProxy from 'http-proxy';
import * as vscode from 'vscode';

/**
 * 代理服务器实现类
 */
export class ProxyServer {
    private server: http.Server | null = null;
    private proxy: httpProxy | null = null;
    private statusBarItem: vscode.StatusBarItem;
    private proxyRules: Map<string, string> = new Map();
    
    constructor() {
        // 创建状态栏项
        this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right);
        this.statusBarItem.text = '$(circle-slash) Nginx代理: 未启动';
        this.statusBarItem.tooltip = 'Nginx配置代理服务器状态';
        this.statusBarItem.command = 'nginx-config-visualizer.toggleProxyServer';
        this.statusBarItem.show();
    }

    /**
     * 启动代理服务器
     */
    public async start(port: number): Promise<boolean> {
        if (this.server) {
            return true; // 已经启动
        }

        try {
            // 创建HTTP代理
            this.proxy = httpProxy.createProxyServer({});
            
            // 创建HTTP服务器
            this.server = http.createServer((req, res) => {
                const url = req.url || '/';
                
                // 查找匹配的路由规则
                let targetFound = false;
                this.proxyRules.forEach((target, path) => {
                    if (url.startsWith(path)) {
                        targetFound = true;
                        // 代理请求到目标服务器
                        console.log(`代理请求: ${url} -> ${target}`);
                        this.proxy?.web(req, res, { target }, (err) => {
                            console.error('代理请求错误:', err);
                            res.writeHead(500, { 'Content-Type': 'text/plain' });
                            res.end('代理错误: ' + err.message);
                        });
                    }
                });
                
                // 如果没有找到匹配的路由规则
                if (!targetFound) {
                    res.writeHead(404, { 'Content-Type': 'text/plain' });
                    res.end('未找到匹配的代理规则');
                }
            });
            
            // 监听错误
            this.server.on('error', (err) => {
                vscode.window.showErrorMessage(`代理服务器错误: ${err.message}`);
                this.stop();
            });
            
            // 启动服务器
            await new Promise<void>((resolve, reject) => {
                this.server?.listen(port, () => {
                    resolve();
                }).on('error', (err) => {
                    reject(err);
                });
            });
            
            // 更新状态栏
            this.statusBarItem.text = `$(check) Nginx代理: 端口${port}`;
            this.statusBarItem.tooltip = `代理服务器运行在端口 ${port}`;
            
            vscode.window.showInformationMessage(`代理服务器已启动，监听端口 ${port}`);
            return true;
        } catch (error) {
            vscode.window.showErrorMessage(`启动代理服务器失败: ${error instanceof Error ? error.message : String(error)}`);
            this.stop();
            return false;
        }
    }

    /**
     * 停止代理服务器
     */
    public stop(): void {
        if (this.server) {
            this.server.close();
            this.server = null;
            this.proxy = null;
            this.proxyRules.clear();
            
            // 更新状态栏
            this.statusBarItem.text = '$(circle-slash) Nginx代理: 未启动';
            this.statusBarItem.tooltip = 'Nginx配置代理服务器状态';
            
            vscode.window.showInformationMessage('代理服务器已停止');
        }
    }

    /**
     * 更新代理规则
     */
    public updateProxyRules(rules: Array<{path: string, target: string}>): void {
        this.proxyRules.clear();
        for (const rule of rules) {
            this.proxyRules.set(rule.path, rule.target);
        }
        
        vscode.window.showInformationMessage(`已更新 ${rules.length} 条代理规则`);
    }

    /**
     * 检查服务器是否运行
     */
    public isRunning(): boolean {
        return this.server !== null;
    }

    /**
     * 切换服务器状态
     */
    public toggle(port: number, rules: Array<{path: string, target: string}>): void {
        if (this.isRunning()) {
            this.stop();
        } else {
            this.updateProxyRules(rules);
            this.start(port);
        }
    }
} 